import TreeSelect from '@/components/TreeSelect';
import type { RoleRecord } from '@/DatabaseType/Role';
import { RoleIsSuper } from '@/DatabaseType/Role';
import { RoleIsSuperMap } from '@/DatabaseType/Role';
import type { UserRecord } from '@/DatabaseType/User';
import {
  addRole,
  deleteRole,
  getRole,
  getRoleList,
  updateRole,
} from '@/services/role';
import { DEFAULT_REQUIRED_RULE, MODAL_TITLE_MAP } from '@/constant';
import { ResponseCode } from '@/utils/request';
import { PlusOutlined } from '@ant-design/icons';
import type { ActionType, ProColumns } from '@ant-design/pro-components';
import { PageContainer, ProTable } from '@ant-design/pro-components';
import { useModel } from '@umijs/max';
import {
  Button,
  Form,
  Input,
  message,
  Modal,
  notification,
  Popconfirm,
  Tag,
} from 'antd';
import { useRef, useState } from 'react';
import { FormLayout } from '../Common/config';

const RoleManagement = () => {
  const { initialState } = useModel('@@initialState');
  const currentUser = initialState?.currentUser as UserRecord;

  const actionRef = useRef<ActionType>();
  const [modalConfig, setModalConfig] = useState<{
    visible: boolean;
    type: 'edit' | 'view' | 'add';
    roleId?: number;
  }>({
    visible: false,
    type: 'add',
  });
  const [formInstance] = Form.useForm();
  const [operateLoading, setOperateLoadingLoading] = useState(false);

  const columns: ProColumns<RoleRecord>[] = [
    {
      title: '主键',
      dataIndex: 'id',
      width: 48,
      align: 'center',
    },
    {
      title: '名称',
      dataIndex: 'name',
    },
    {
      title: '角色类型',
      dataIndex: 'isSuper',
      valueEnum: RoleIsSuperMap,
      render(dom, { isSuper }) {
        const config = RoleIsSuperMap[isSuper];
        return <Tag color={config.status}>{config?.text}</Tag>;
      },
    },
    {
      title: '中文名称',
      dataIndex: 'znName',
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      valueType: 'dateTime',
      sorter: true,
      hideInSearch: true,
    },
    {
      title: '更新时间',
      dataIndex: 'updateTime',
      valueType: 'dateTime',
      sorter: true,
      hideInSearch: true,
    },
    {
      title: '操作',
      valueType: 'option',
      render: (text, { id: roleId, isSuper }) => {
        const isSuperAdmin = isSuper === RoleIsSuper.Yes;
        // 如果是超管不能有任何被操作行为
        if (isSuperAdmin) return [];
        return [
          <a
            key="view-detail"
            onClick={() => {
              // 打开弹窗
              setModalConfig((config) => ({
                ...config,
                visible: true,
                type: 'view',
                roleId,
              }));
              // 获取详情写入表单
              viewDetail(roleId);
            }}
          >
            查看
          </a>,
          <a
            key="edit-detail"
            onClick={() => {
              // 打开弹窗
              setModalConfig((config) => ({
                ...config,
                visible: true,
                type: 'edit',
                roleId,
              }));
              // 获取详情写入表单
              viewDetail(roleId);
            }}
          >
            编辑
          </a>,
          <Popconfirm
            key="delete-detail"
            title="确认删除该记录吗？"
            okText="是"
            cancelText="否"
            onConfirm={() => sureDeleteRole(roleId)}
          >
            <a href="#">删除</a>
          </Popconfirm>,
        ];
      },
    },
  ];

  // 确认删除角色
  async function sureDeleteRole(roleId: number) {
    try {
      const { code, message: msg } = await deleteRole(roleId);
      if (code === ResponseCode.Success) {
        notification.success({ message: '删除成功' });
        actionRef.current?.reload();
      } else {
        notification.error({ message: msg || '删除失败' });
      }
    } catch (error: any) {
      notification.error({ message: error?.message || '删除角色失败' });
    }
  }

  // 获取角色详情并切入到表单Form
  async function viewDetail(roleId: number) {
    try {
      const { code, data: roleRecord, message: msg } = await getRole(roleId);
      if (code === ResponseCode.Success) {
        const { permissionList } = roleRecord;
        formInstance.setFieldsValue({
          name: roleRecord.name,
          znName: roleRecord.znName,
          permissionIds: permissionList.map((item) => item.id),
        });
      } else {
        message.error(msg);
      }
    } catch (error: any) {
      console.log('RoleManagement => index => getRole', '请求失败');
    }
  }

  // proTable 获取角色列表方法
  async function request(params: any) {
    try {
      const { code, data, message: msg } = await getRoleList(params);
      if (code === ResponseCode.Success) {
        return {
          data: data.list,
          total: data.total,
        };
      }
      throw new Error(msg);
    } catch (error: any) {
      console.log('RoleManagement => index => getRoleList', '请求失败');
      return {
        data: [],
        total: 0,
      };
    }
  }

  // 弹窗点击确认，提交表单
  async function sureAddRole() {
    switch (modalConfig.type) {
      // 新增时
      case 'add': {
        // 获取表单数据
        const formData = await formInstance.validateFields();
        // 弹窗确认按钮loading
        setOperateLoadingLoading(true);
        try {
          const {
            code,
            data: newRoleId,
            message: msg,
          } = await addRole(formData);
          if (code === ResponseCode.Success) {
            setModalConfig((config) => ({ ...config, visible: false }));
            actionRef.current?.reload();
            notification.success({ message: `新增角色ID: ${newRoleId}成功` });
          } else {
            notification.error({ message: msg || '新增角色失败' });
          }
        } catch (error: any) {
          notification.error({ message: error?.message || '新增角色失败' });
        }
        setOperateLoadingLoading(false);
        break;
      }
      // 修改时
      case 'edit': {
        const formData = await formInstance.validateFields();
        setOperateLoadingLoading(true);
        try {
          const { code, message: msg } = await updateRole(
            modalConfig.roleId as number,
            formData,
          );
          if (code === ResponseCode.Success) {
            setModalConfig((config) => ({ ...config, visible: false }));
            actionRef.current?.reload();
            notification.success({ message: `更新角色成功` });
            // 当前操作涉及登入用户（权限），登入用户重新更新
            if (
              currentUser.roles.find((role) => role.id === modalConfig.roleId)
            ) {
              window.location.reload();
            }
          } else {
            notification.error({ message: msg || '更新角色失败' });
          }
        } catch (error: any) {
          notification.error({ message: error?.message || '更新角色失败' });
        }
        setOperateLoadingLoading(false);
        break;
      }
      // 查看时
      case 'view':
        setModalConfig((config) => ({ ...config, visible: false }));
        break;
    }
  }

  return (
    <PageContainer className="role-list">
      <ProTable<RoleRecord>
        columns={columns}
        actionRef={actionRef}
        request={async (params = {}) => {
          return request(params);
        }}
        rowKey="id"
        search={{
          labelWidth: 100,
          defaultCollapsed: false,
        }}
        pagination={{
          pageSize: 5,
        }}
        dateFormatter="string"
        toolBarRender={() => [
          <Button
            key="add-detail"
            icon={<PlusOutlined />}
            type="primary"
            onClick={() => {
              formInstance.resetFields();
              setModalConfig((config) => ({
                ...config,
                visible: true,
                type: 'add',
              }));
            }}
          >
            新增
          </Button>,
        ]}
      />
      <Modal
        title={MODAL_TITLE_MAP[modalConfig.type]}
        open={modalConfig.visible}
        onCancel={() =>
          setModalConfig((config) => ({
            ...config,
            visible: false,
            roleId: undefined,
          }))
        }
        onOk={sureAddRole}
        confirmLoading={operateLoading}
      >
        <Form
          {...FormLayout}
          form={formInstance}
          disabled={modalConfig.type === 'view'}
        >
          <Form.Item
            name="name"
            label="角色英文名"
            rules={DEFAULT_REQUIRED_RULE}
          >
            <Input />
          </Form.Item>
          <Form.Item
            name="znName"
            label="角色中文名"
            rules={DEFAULT_REQUIRED_RULE}
          >
            <Input />
          </Form.Item>
          <Form.Item name="permissionIds" label="权限管理">
            <TreeSelect disabled={modalConfig.type === 'view'} />
          </Form.Item>
        </Form>
      </Modal>
    </PageContainer>
  );
};

export default RoleManagement;
